﻿using HsServerHa.Common;
using HsServerHa.Common.Auth;
using HsServerHa.Entity.Models;
using HsServerHa.Utility.DataHelper;
using HsServerHa.Utility.SQLite;
using Quartz;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace HsServerHa.Jobs
{
    [DisallowConcurrentExecution]
    public class CheckProgramTaskJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            #region 授权验证
            if (!AuthorizationVerification.IsVerification())
            {
                return;
            }
            #endregion
            await CheckProgram().ConfigureAwait(false);
            await CheckDaemon().ConfigureAwait(false);
            await CheckSyncFile().ConfigureAwait(false);
        }
        /// <summary>
        /// 检查程序状态
        /// </summary>
        /// <returns></returns>
        public async Task CheckProgram()
        {
            if (App.isMaster != null)
            {
                if (App.isMaster.Value)
                {
                    //查询数据
                    List<ProgramManageEntity> programList = await SQLiteHelper.TableAsync<ProgramManageEntity>().Where(x=>x.IsEnable=="是").OrderBy(x => x.StartupSeq).ToListAsync().ConfigureAwait(false);
                    if (programList == null)
                    {
                        return;
                    }

                    var appProcess = App.ProcessList;

                    var delList = new List<Process>();
                    foreach (var item in programList)
                    {
                        if (item.IsEnable == "是")
                        {
                            var proFirst = appProcess.FirstOrDefault(x => item.Src.Contains(x.ProcessName));
                            var timer = 0;
                            int.TryParse(item.Delayed, out timer);
                            if (proFirst == null)
                            {

                                Thread.Sleep(timer * 1000);
                                HandlerProgram.AddProgram(item.Src);
                                break;
                            }
                            if (proFirst.HasExited)
                            {
                                Thread.Sleep(timer * 1000);
                                HandlerProgram.AddProgram(item.Src);
                                delList.Add(proFirst);
                                break;
                            }
                        }
                        //else
                        //{
                        //    var proFirst = appProcess.FirstOrDefault(x => item.Src.Contains(x.ProcessName));
                        //    if (proFirst != null)
                        //    {
                        //        HandlerProgram.RemoveProgram(item.Src);
                        //    }
                        //}

                    } 
                    foreach (var item in appProcess)
                    {
                        var proFirst = programList.FirstOrDefault(x => x.Src.Contains(item.ProcessName));
                        if (proFirst == null)
                        {
                            if (!item.HasExited)
                            {
                                item.Kill();
                            }
                            delList.Add(item);
                        }
                    }
                    foreach (var item in delList)
                    {
                        App.ProcessList.Remove(item);
                    }
                }
                else
                {
                    HandlerProgram.RemoveProgramAll();
                    //var sqlPro = "select * from ProgramManage";
                    //var dtPro = DbHelperSQLite.Query(sqlPro)?.Tables?[0];
                    //List<ProgramManageEntity> listPro = DataHelpers.ConvertToModel<ProgramManageEntity>(dtPro);

                    List<ProgramManageEntity> programList = await SQLiteHelper.TableAsync<ProgramManageEntity>().Where(x=>x.IsEnable=="是").ToListAsync().ConfigureAwait(false);
                    if (programList == null)
                    {
                        return;
                    }
                    foreach (var item in programList)
                    {
                        var proNames = item.Src.ToString().Split("\\");
                        if (string.IsNullOrEmpty(item.Src))
                        {
                            continue;
                        }
                        var ProcessNames = item.Src.ToString().Split("\\");
                        var ProcessName = ProcessNames[ProcessNames.Length - 1].Replace(".exe", ""); ;
                        Process[] MyProcess = Process.GetProcessesByName(ProcessName);
                        foreach (var p in MyProcess)
                        {
                            p.Kill();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 检测守护进程
        /// </summary>
        /// <returns></returns>
        public async Task CheckDaemon() {
            try
            {
                var IsStartDaemon = false;
                bool.TryParse(IniFileConfig.Current.GetStringValue("UserConfig", "IsStartDaemon"), out IsStartDaemon);
                var path = System.Environment.CurrentDirectory;

                var FilePath = path + "\\Daemon\\HsServerHa.Monitor.exe";
                var ProcessName = "HsServerHa.Monitor";
                if (!HandlerProgram.IsProcessRunning("HsServerHa.Monitor"))
                {
                    if (!IsStartDaemon)
                    {
                        return;
                    }
                    var CurrFileName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
                    //ProcessStartInfo startInfo = new ProcessStartInfo();
                    //startInfo.UseShellExecute = false;
                    //startInfo.RedirectStandardInput = true;
                    //startInfo.RedirectStandardOutput = false;
                    //startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    //startInfo.WindowStyle = ProcessWindowStyle.Minimized;
                    //startInfo.FileName = FilePath; // 替换为您的WPF程序的路径
                    //ArgsBuilder arg = new ArgsBuilder();
                    //arg.Add("HsServerHa");
                    //arg.Add(CurrFileName);
                    //startInfo.Arguments = arg.ToString();
                    //Process.Start(startInfo);

                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    startInfo.FileName = FilePath;
                    startInfo.UseShellExecute = false;
                    startInfo.CreateNoWindow = true;
                    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    ArgsBuilder arg = new ArgsBuilder();
                    arg.Add("HsServerHa");
                    arg.Add(CurrFileName);
                    startInfo.Arguments = arg.ToString();
                    Process process = new Process();
                    process.StartInfo = startInfo;
                    process.Start();
                }
                else
                {
                    if (!IsStartDaemon)
                    {
                        //关闭
                        HandlerProgram.KillProcessByName(ProcessName);
                    }
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Error(ex.Message+ex.ToString());
            }
        
        }

        /// <summary>
        /// 检测文件同步
        /// </summary>
        /// <returns></returns>
        public async Task CheckSyncFile()
        {
            var IsStartSyncFile = false;
            bool.TryParse(IniFileConfig.Current.GetStringValue("UserConfig", "IsStartSyncFile"), out IsStartSyncFile);
            var path = System.Environment.CurrentDirectory;

            var FilePath = path + "\\SyncFiles\\syncthing.exe";
            var ProcessName = "syncthing";
            if (!HandlerProgram.IsProcessRunning("syncthing"))
            {
                if (!IsStartSyncFile)
                {
                    return;
                }
                var CurrFileName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; 

                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = FilePath;
                startInfo.UseShellExecute = false;
                startInfo.CreateNoWindow = true;
                startInfo.WindowStyle = ProcessWindowStyle.Hidden; 
                Process process = new Process();
                process.StartInfo = startInfo;
                process.Start();
            }
            else
            {
                if (!IsStartSyncFile)
                {
                    //关闭
                    HandlerProgram.KillProcessByName(ProcessName);
                }
            }
        }
    }

    /// <summary>
    /// 参数构建类
    /// </summary>
    public class ArgsBuilder
    {
        StringBuilder _arg = new StringBuilder();
        public ArgsBuilder()
        {
            _arg.Append("");
        }

        /// <summary>
        /// 添加参数
        /// </summary>
        /// <param name="str"></param>
        public void Add(string str)
        {
            if (str.EndsWith("\\"))  //处理最后若为“\\”，会被转义成“\”，然后变成转义符。
            {
                str += "\\";
            }
            _arg.AppendFormat("\"{0}\"", str);
            _arg.Append(" "); //参数分割符号
        }
        public override string ToString()
        {
            return _arg.ToString();
        }
    }
}
